//
//  Seralizer.m
//  gongwei-ios
//
//  Created by xiaoxiachuanqi on 2020/1/22.
//  Copyright © 2020 gongwei-mac. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <objc/runtime.h>
#import "Serializer.h"
#import "JsonSerializable.h"
#import "TypeFactory.h"
#import "JsonTagType.h"

@implementation Serializer

+(BOOL)isJsonSerializable:(NSObject *)obj {
    return obj && [obj isMemberOfClass: [JsonSerializable class]];
}

+(id) parseData:(NSObject *)obj {
    if(!obj) {
        return nil;
    }
    
    if([obj isKindOfClass:[NSArray class]]) {
        // json数组
        NSArray *arrayResult = (NSArray *)obj;
        
        if (arrayResult.count == 2 && [[arrayResult objectAtIndex: 0] isKindOfClass: [NSString class]]) {
            // class 解析
            NSString *javaClass = [arrayResult objectAtIndex: 0];
            NSObject *value = [arrayResult objectAtIndex: 1];
            if([Serializer isJavaArray: javaClass] || [Serializer isJavaArrayList: javaClass]) {
                // 里面还是个数组
                return [Serializer parseJsonArray:(NSArray *)value];
            } else if ([Serializer isJavaMapName: javaClass]) {
                return [Serializer parseObjectToDictionary:value];
            } else if ([Serializer isJavaLongName: javaClass]) {
                NSNumber *num = [NSNumber numberWithLong: (long)value];
                return num;
            } else if ([Serializer isJavaStringName: javaClass]) {
                return value;
            } else if ([Serializer isJavaBooleanName: javaClass]) {
                return value;
            } else {
                JsonSerializable *jsonSerializable = [TypeFactory createInstanceByClassId: javaClass];
                if(jsonSerializable) {
                    // 可序列化自定义json对象
                    [jsonSerializable fillFromDictionary: [Serializer parseObjectToDictionary: [arrayResult objectAtIndex: 1]]];
                    return jsonSerializable;
                }
            }
        }
        
        
        //
        NSArray *resultArray = [Serializer parseJsonArray:arrayResult];
        return resultArray;
    } else if([obj isKindOfClass:[NSDictionary class]]) {
        // json 对象
        NSDictionary *dictionaryResult = (NSDictionary *)obj;
        
        if (dictionaryResult[@"__type"])
        {
            NSString *javaType = dictionaryResult[@"__type"];
            JsonSerializable *jsonSerializable = [TypeFactory createInstanceByTypeId:javaType];
            
            if (jsonSerializable)
            {
                [jsonSerializable fillFromDictionary: dictionaryResult];
                return jsonSerializable;
            }
        }
        
        return [Serializer parseObjectToDictionary: obj];
    } else {
        return obj;
    }
}


    
+(id)parseJsonString:(NSString *)jsonStr
{
    NSData *data= [jsonStr dataUsingEncoding:NSUTF8StringEncoding];
    NSError *error = nil;
    NSObject *obj =
    [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error: &error];
    return [Serializer parseData: obj];
}


+(NSMutableArray *)parseJsonArray:(NSArray *)array
{
    NSMutableArray *result = [NSMutableArray array];
    unsigned long count = array.count;
    long i;
    for (i = 0; i < count; i ++)
    {
        id value = [array objectAtIndex: i];
        value = [Serializer parseData: value];
        if (value)
        {
            [result addObject: value];
        }
    }
    return result;
}

+(NSMutableDictionary *)parseObjectToDictionary:(NSObject *)obj
{
    NSMutableDictionary *dic = [NSMutableDictionary dictionary];
    unsigned int propsCount;
    objc_property_t *props = class_copyPropertyList([obj class], &propsCount);
    for(int i = 0;i < propsCount; i++)
    {
        objc_property_t prop = props[i];
        
        NSString *propName = [NSString stringWithUTF8String:property_getName(prop)];//获得属性的名称
        id value = [obj valueForKey:propName];//kvc读值
        if(value != nil)
        {
            value = [Serializer parseData: value];
            [dic setObject:value forKey:propName];
        }
        
    }
    return dic;
}

+(BOOL)isJavaArrayList:(NSString *)className
{
    return [className isEqualToString: @"java.util.ArrayList"];
}

+(BOOL)isJavaArray:(NSString *)className
{
    return [className isEqualToString: @"Ljava.lang.Object;"];
}

+(BOOL)isJavaObjectName:(NSString *)className
{
    return [className isEqualToString:@"java.lang.Object"];
}

+(BOOL)isJavaMapName:(NSString *)className
{
    return [className isEqualToString:@"java.util.HashMap"];
}

+(BOOL)isJavaLongName:(NSString *)className
{
    return [className isEqualToString:@"java.lang.Long"];
}

+(BOOL)isJavaStringName:(NSString *)className {
    return [className isEqualToString:@"java.lang.String"];
}

+(BOOL)isJavaBooleanName:(NSString *)className {
    return [className isEqualToString:@"java.lang.Boolean"];
}

+(id)parseObjectToJsonString:(NSObject *)source {
    id obj = [Serializer parseObjectToData: source];
    
    NSData *data=[NSJSONSerialization dataWithJSONObject:obj options:NSJSONWritingPrettyPrinted error:nil];
    NSString *jsonStr=[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
    return jsonStr;
}

+(id)parseObjectToData:(id)obj {
    return [self parseObjectToData:obj withJsonTagType:JTT_TYPE];
}

+(id)parseObjectToData:(NSObject *)obj withJsonTagType:(JsonTagType)jsonTagType {
    if (obj == nil) {
        return nil;
    }
    
    NSLog(@"type: %d, class:%@", jsonTagType, [obj class]);
    
    if ([obj isKindOfClass:[NSArray class]]) {
        return [[NSArray alloc] initWithObjects: @"Ljava.lang.Object;", [Serializer parseArrayToData: (NSArray *)obj withJsonTagType:jsonTagType], nil];
    }
    else if ([obj isKindOfClass:[NSNumber class]]) {
        return obj;
    }
    else if ([obj isKindOfClass:[NSString class]]) {
        return obj;
    }
    else if ([obj isKindOfClass: [JsonSerializable class]]){
        return [(JsonSerializable *)obj getJson: jsonTagType];
    }
    else if ([obj isKindOfClass:[NSDictionary class]])
    {
        return [self parseDictionaryToData:(NSDictionary *)obj withJsonTagType:jsonTagType];
    }
    else {
        return obj;
    }
}

+(id)parseArrayToData:(NSArray *)arr withJsonTagType:(JsonTagType)jsonTagType{
    NSMutableArray *result = [NSMutableArray array];
    unsigned long count = arr.count;
    unsigned long i;
    for (i = 0; i < count; i ++)
    {
        NSObject *item = [arr objectAtIndex: i];
        [result addObject: [Serializer parseObjectToData: item withJsonTagType: jsonTagType]];
    }
    return result;
}

+(id)parseDictionaryToData:(NSDictionary *)dictionary withJsonTagType:(JsonTagType)jsonTagType {
    NSArray* keyArray = [dictionary allKeys];
    NSMutableDictionary* newDictionary = [NSMutableDictionary dictionary];
    for (NSString * key in keyArray)
    {
        [newDictionary setObject:[self parseObjectToData:dictionary[key] withJsonTagType:jsonTagType] forKey:key];
    }
    return newDictionary;
}

@end
